#ifndef _GOVT_ECONOMY_HPP
#define _GOVT_ECONOMY_HPP
/*******************************************************************************
 ** Name: economy.hpp                                                         **
 ** Description: WorldObject-derived container objects                        **
 **                                                                           **
 ** Open Source Initiative (OSI) Approved License                             **
 **                                                                           **
 ** The contents of this file are subject to the terms of the                 **
 ** Common Development and Distribution License, Version 1.0 only             **
 ** (the "License").  You may not use this file except in compliance          **
 ** with the License.                                                         **
 **                                                                           **
 ** You can find a copy of the license in the LICENSE file within             **
 ** this distribution or at $WIKI/display/GOVT/License-software.              **
 ** Software distributed under the License is distributed on an "AS IS"       **
 ** basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.           **
 ** See the License for the specific language governing permissions           **
 ** and limitations under the License.                                        **
 **                                                                           **
 ** When distributing Covered Code, include this CDDL header in each          **
 ** file and include the License file at $GAME_DIR/LICENSE.                   **
 ** If applicable, add the following below this header, with the indicated    **
 ** fields enclosed by brackets "[]" replaced with your own identifying       **
 ** information: Portions Copyright [yyyy] [name of copyright owner]          **
 **                                                                           **
 ** Copyright (c) 2009-2011  Barry Gian James <gian@gamingods.net>            **
 ** All rights reserved.                                                      **
 ******************************************************************************/
// Portions (c) 2012 Open Design Strategies, LLC.
// Modified $Date$ by $Author$
#define economy_hpp_ID   "$Id$"

#include "stocks.hpp"

// The default starting-out credit rating
const int	DEFAULT_CREDIT_RATING = 500;

// How much scratch is floating in the economy
extern unsigned long marketCurrency;

enum class RepaymentSchedule { Weekly, Monthly };

#pragma db object table("bank_accounts")
struct DepositAccount
{
	#pragma db id
	entity_t	idcharacter_;
	entity_t	idaccount_;	// idbank_account from DB
	entity_t	idbank_;		// idbank from DB
	uint64_t	amount_;
};

//! @struct Loan
//! @brief Definition of a bank loan
#pragma db object table("loans")
class Loan
{
public:
	Loan();

	int		TotalNumPayments() {
		return payments_made_ + payments_due_ + payments_pastdue_30_
				+ payments_pastdue_60_ + payments_pastdue_90_;
	}
	void	MakePayment() {++payments_made_; --payments_due_; }
	void	OneMonthDefault() { ++payments_pastdue_30_; }
	void	TwoMonthDefault() { OneMonthDefault(); --payments_pastdue_30_; ++payments_pastdue_60_; }
	void	ThreeMonthDefault() { TwoMonthDefault(); --payments_pastdue_60_; ++payments_pastdue_90_; }

	const entity_t	ID() const { return idloan_; }
	const entity_t	Owner() const { return idcharacter_; }
	const entity_t	Issuer() const { return idbank_; }
	const uint32_t	Amount() const { return amount_; }
	const double   Interest() const { return interest_; }
	const int	PaymentsDue() const { return payments_due_; }
	const int	PaymentsMade() const { return payments_made_; }
	const int	PaymentsDefault30() const { return payments_pastdue_30_; }
	const int	PaymentsDefault60() const { return payments_pastdue_60_; }
	const int	PaymentsDefault90() const { return payments_pastdue_90_; }
	RepaymentSchedule PaymentSchedule() { return _sched; }
	int	PaymentAmount() { return ceil((double)(amount_ / TotalNumPayments())); }
	int	CalcInterest() { return ceil(PaymentAmount() * interest_); }

	void	Owner(entity_t o) { idcharacter_ = o; }
	void	Issuer(entity_t i) { idbank_ = i; }
	void	Amount(uint32_t a) { amount_ = a; }
	void	Interest(double i) { interest_ = i; }
	void	PaymentsDue(int p) { payments_due_ = p; }


private:
	friend class odb::access;

	#pragma db id auto
	entity_t	idloan_;
	entity_t	idcharacter_;
	entity_t	idbank_;	// issuing bank
	uint32_t	amount_;
	uint32_t	paid_;
	double	interest_;
	int		payments_made_;
	int		payments_due_;
	int		payments_pastdue_30_;
	int		payments_pastdue_60_;
	int		payments_pastdue_90_;
	entity_t	idcollateral_;	// maybe should be a list of items
	RepaymentSchedule _sched;


};

//! @class CentralBank
//! @brief The government bank
#pragma db object table("bank_central")
class CentralBank
{
public:
	CentralBank();

	const double  InterestRate() const { return interestRate_; }
	const double BondYield() const { return bondYield_; }
	const int BondDueMax() const { return bondDueMax_; }
	const uint64_t Reserve() const { return reserve_; }

	void InterestRate(double i) { interestRate_ = i; }
	void BondYield(double i) { bondYield_ = i; }
	void BondDueMax(int i) { bondDueMax_ = i; }
	void Reserve(uint64_t i) { reserve_ = i; }

private:
	friend class odb::access;

	#pragma db id
	std::string	_name;
	double	interestRate_;	// maximum interest rate for loans
	double	bondYield_;		// minimum bond annual interest
	int	bondDueMax_;		// maximum years for bonds to be paid back
	uint64_t	reserve_;		// minimum reserve scratch for banks
};

#pragma db value
struct BusinessInventory
{
	entity_t	_id;
	unsigned int	_price;
	unsigned int	_num;
};

//! @class Business
//! @brief basic business base class
#pragma db object table("business")
class Business
{
public:

	// Getters
	const entity_t ID() const { return _id; }
	const std::string & Name() const { return _name; }
	const entity_t Owner() const { return _owner; }
	const std::list<entity_t> & Employees() const { return _employees; }
	const std::string & Address() const { return _address; }
	const std::list<BusinessInventory> & Inventory() const { return _inventory; }
	const std::list<Stock> & Stocks() const { return _stocks; }
	const uint64_t Value() const { return _value; }

	// Setters

protected:
	#pragma db id auto
	entity_t	_id;
	std::string	_name;
	entity_t	_owner;
	std::list<entity_t>	_employees;
	std::string	_address;
	std::list<BusinessInventory> _inventory;
	std::list<Stock>	_stocks;
	uint64_t	_value;
};


#endif /* _GOVT_ECONOMY_HPP */
